package com.tang.plugin.utils;

import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;

public class PluginKit {

    private static volatile PluginKit INSTANCE;
    private AnActionEvent e;
    private Project project;

    private PluginKit(AnActionEvent e) {
        this.e = e;
        this.project = e.getProject();
    }

    public static PluginKit getInstance(AnActionEvent e) {
        if (INSTANCE == null) {
            synchronized (PluginKit.class) {
                if (INSTANCE == null) {
                    INSTANCE = new PluginKit(e);
                }
            }
        }
        return INSTANCE;
    }

    public static FileTemplate[] getAllFileTemplate() {
        return FileTemplateManagerImpl.getDefaultInstance().getAllTemplates();
    }

    public static FileTemplate getFileTemplate(String name) {
        return FileTemplateManagerImpl.getDefaultInstance().getTemplate(name);
    }

    public Project getProject() {
        return project;
    }

    public boolean isProjectValid() {
        return project.isOpen() && project.isInitialized();
    }

    public static void showErrorMessage(String message) {
        Messages.showDialog(message, "提示", new String[]{}, 0, Messages.getErrorIcon());
    }

    public VirtualFile getVirtualFile() {
        return e.getData(PlatformDataKeys.PROJECT_FILE_DIRECTORY);
    }

    public VirtualFile createDir(String name, VirtualFile vf) {
        if (vf == null || !vf.isDirectory()) {
            showErrorMessage("目标不是目录");
            return null;
        }
        VirtualFile child = vf.findChild(name);
        if (child != null && child.exists()) {
            return child;
        }
        try {
            return vf.createChildDirectory(null, name);
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public PsiElement createFileFromTemplate(String fileName, String templateName, Map<String, String> propertiesMap, VirtualFile directory) {
        FileTemplateManager fileTemplateManager = FileTemplateManager.getInstance(project);
        Properties properties = new Properties(fileTemplateManager.getDefaultProperties());
        propertiesMap.forEach((k, v) -> properties.setProperty(k.strip(), v));
        FileTemplate template = fileTemplateManager.getTemplate(templateName);
        if (template == null) {
            return null;
        }
        PsiDirectory psiDirectory = getPsiDirectoryByVirtualFile(directory);
        if (psiDirectory == null) {
            return null;
        }
        try {
            return FileTemplateUtil.createFromTemplate(template, fileName, properties, psiDirectory);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private PsiDirectory getPsiDirectoryByVirtualFile(VirtualFile directory) {
        if (!directory.isDirectory()) {
            showErrorMessage(directory.getPath() + "不是目录");
            return null;
        }
        return PsiManager.getInstance(project).findDirectory(directory);
    }

    public boolean createFile(String name, VirtualFile directory) {
        if (!checkCreateFile(name, directory)) {
            return false;
        }
        try {
            directory.createChildData(null, name);
            return true;
        } catch (IOException ex) {
            ex.printStackTrace();
            return false;
        }
    }

    private boolean checkCreateFile(String name, VirtualFile directory) {
        if (directory == null || !directory.isDirectory()) {
            showErrorMessage("目标不是目录");
            return false;
        }
        VirtualFile child = directory.findChild(name);
        return child == null || !child.exists();
    }
}
